package com.noah.project.socket

import com.corundumstudio.socketio.AckRequest
import com.corundumstudio.socketio.SocketIOClient
import com.corundumstudio.socketio.SocketIOServer
import com.corundumstudio.socketio.annotation.OnConnect
import com.corundumstudio.socketio.annotation.OnDisconnect
import com.corundumstudio.socketio.annotation.OnEvent
import com.noah.project.global.Const
import com.noah.project.global.JsonManager
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component

import java.util.UUID
import java.util.concurrent.ConcurrentHashMap


@Component
class MsgHandler @Autowired
constructor(server: SocketIOServer) {
    val log = LoggerFactory.getLogger(MsgHandler::class.simpleName)
    var socketIoServer: SocketIOServer = server
    companion object {
        private val mapClient = ConcurrentHashMap<Long, UUID>()
    }

    @OnConnect
    fun onConnect(client: SocketIOClient?) {
        if (client != null) {
            val uidString = client.handshakeData.getSingleUrlParam("uid")
            val uid = java.lang.Long.parseLong(uidString)
            put(uid, client.sessionId)
        } else {
            log.error("客户端为空")
        }
    }

    @OnDisconnect
    fun onDisconnect(client: SocketIOClient) {
        remove(client.sessionId)
    }

    @OnEvent(value = Const.EVENT_MESSAGE)
    fun onEvent(client: SocketIOClient, request: AckRequest, data: String) {
        if (request.isAckRequested) {
            request.sendAckData("OK")
        }
        val msgEvent = JsonManager.fromJson(data, MsgEvent::class.java)
        log.info(client.sessionId.toString() + "=>发来消息:" + msgEvent?.toString())

        msgEvent?.time = System.currentTimeMillis()
        val uid = getUid(client.sessionId)
        sendClientMsg(uid, JsonManager.toJson(msgEvent))
    }

    private fun sendClientMsg(uid: Long, data: String) {   //这里就是向客户端推消息了
        val uuid = getUUID(uid)
        socketIoServer.getClient(uuid).sendEvent(Const.EVENT_MESSAGE, data)
    }

    private fun put(uid: Long, uuid: UUID) {
        if (mapClient.containsKey(uid)) {
            mapClient.remove(uid)
        }
        mapClient.put(uid,uuid)
        log.info(uuid.toString() + "=>已连接,现有:" + mapClient.size)
    }

    private fun remove(uuid: UUID) {
        if (mapClient.containsValue(uuid)) {
            for ((key, value) in mapClient) {
                if (value == uuid) {
                    mapClient.remove(key)
                }
            }
        }
        log.info(uuid.toString() + "=>已断开,剩下:" + mapClient.size)
    }

    private fun getUUID(uid: Long): UUID? {
        return mapClient.get(uid)
    }

    private fun getUid(uuid: UUID): Long {
        if (mapClient.containsValue(uuid)) {
            for ((key, value) in mapClient) {
                if (value == uuid) {
                    return key
                }
            }
        }
        return 0L
    }
}